package token

import (
	"context"
	"time"

	"mall/common/globalkey"
	"mall/service/backend/common/errorx"
	"mall/service/backend/common/i18n"
	"mall/service/backend/common/msg/logmsg"
	"mall/service/backend/model"
	"mall/service/backend/rpc/internal/svc"
	"mall/service/backend/rpc/internal/utils/errorhandler"
	"mall/service/backend/rpc/types/backend"

	"github.com/zeromicro/go-zero/core/logx"
)

type BlockUserAllTokenLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewBlockUserAllTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BlockUserAllTokenLogic {
	return &BlockUserAllTokenLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *BlockUserAllTokenLogic) BlockUserAllToken(in *backend.UUIDReq) (*backend.BaseResp, error) {
	if len(in.Id) == 0 {
		return nil, errorx.NewInvalidArgumentError(i18n.ValidationError)
	}

	filterMap := make(map[string]map[string][]any)
	filterMap[model.SysTokenColumns.UUID] = map[string][]any{
		"equalTo": []any{in.Id},
	}
	filterMap[model.SysTokenColumns.Status] = map[string][]any{
		"equalTo": []any{uint8(globalkey.StatusEnabled)},
	}
	tokens, _, err := l.svcCtx.SysToken.GetList(l.ctx, model.M{}, -1, filterMap)
	if err != nil {
		return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
	}

	if len(tokens) > 0 {
		var ids []uint64
		nowTime := time.Now().Unix()
		for _, v := range tokens {
			ids = append(ids, v.ID)
			if v.ExpiredAt.Valid {
				expiredTime := int(v.ExpiredAt.Time.Unix() - nowTime)
				if expiredTime > 0 {
					err = l.svcCtx.BizRedis.Setex("token_"+v.Token, "1", expiredTime)
					if err != nil {
						logx.Errorw(logmsg.RedisError, logx.Field("detail", err.Error()))
						return nil, errorx.NewInternalError(i18n.RedisError)
					}
				}
			}
		}

		err = l.svcCtx.SysToken.UpdateBatch(l.ctx, nil, ids, model.M{
			model.SysTokenColumns.Status: uint8(globalkey.StatusDisabled),
		}, nil)
		if err != nil {
			return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
		}
	}

	return &backend.BaseResp{
		Msg: i18n.UpdateSuccess,
	}, nil
}
